﻿!function () {
  if (location.pathname == '/') { // 在首页
    let reWhite                  = /Java|Android|PHP|MySQL|JFinal|Spring|Python|Eclipse|jQuery|Tomcat|Linux|ECharts|Ubuntu|Nginx|CentOS|Oracle|Android SDK|Hibernate|iOS|Apache|Struts|Maven|MyEclipse|Git|Qt|IntelliJ IDEA|Hadoop|C\+\+|Windows|ExtJS|MongoDB|Java EE|Xcode|Visual Studio|EasyUI|MyBatis|Druid|Lucene|Django|Redis|SQL Server|Subversion (SVN)|jQuery Mobile|JSON|PostgreSQL|SpringSide|Fedora Linux|Chrome|zTree|Netty|JavaScript|JDK|KindEditor|FreeMarker|ThinkPHP|Shiro|memcached|Bootstrap|Node/i, // 白名单
        domParser                = new DOMParser(),
        deleted                  = JSON.parse(localStorage.getItem('deleted')) || [], // 已处理过的帖子id
        ignored                  = JSON.parse(localStorage.getItem('ignored')) || [], // 已忽略的帖子id
        lastDeleted              = JSON.parse(localStorage.getItem('lastDeleted')) || [], // 过去十条处理过的帖子标题, 用来捉一些漏网之鱼
        similarityThreshold      = 0.15, // 单条检测重复度阈值, 大于等于才加入总重复度, 范围0-1.
        totalSimilarityThreshold = 1, // 总重复度阈值, 和其他帖子重复度之和大于等于此数才会列为可疑帖子.
        suspiciousThreshold      = 1, // 可疑帖子数量阈值, 大于等于才提示.
        checkInterval            = 60e3, // 检测间隔, 60秒
        sortChar                 = false, // 测重时是否排序, 可提高精确度
        userCode                 = $('[name=user_code]').val() //

    // 检测相似度, Levenshtein Distance
    let toCharArr = _.memoize(str => {
      let chars = str.split('')
      return sortChar ? chars.sort() : chars
    })
    function minConvStep(s1 = '', s2 = '') {
      let charArr = [s1, s2].map(toCharArr), arr = []
      for (let i = 0; i <= charArr[0].length; i++) {
        arr[i] = []
        for (let j = 0; j <= charArr[1].length; j++) {
          if (i * j == 0) {
            arr[i][j] = j + i
          } else {
            arr[i][j] = Math.min(arr[i - 1][j - 1] + (charArr[0][i - 1] == charArr[1][j - 1] ? 0 : 1),
              arr[i - 1][j] + 1, arr[i][j - 1] + 1)
          }
        }
      }
      return arr[charArr[0].length][charArr[1].length]
    }
    let calcSimilarity = _.memoize((s1 = '', s2 = '') => {
      return 1 - minConvStep(s1, s2) / Math.max(1, s1.length, s2.length)
    }, (s1 = '', s2 = '') => s1 > s2 ? s1 + s2 : s2 + s1)

    // java stirng hashcode的js实现
    function hashCode(str) {
      let hash = 0
      if (str.length == 0) return hash
      for (let i = 0; i < str.length; i++) {
        let char = str.charCodeAt(i)
        hash = ((hash << 5) - hash) + char
        hash = hash & hash // Convert to 32bit integer
      }
      return hash
    }
    let getArticleHashCode = _.memoize(href =>
      hashCode(href.substr(href.lastIndexOf('/') + 1).split('_').reverse().join('_')))

    // localStorage 往数组添加元素
    function addLocalStorage(key, value, maxLen) {
      let item = JSON.parse(localStorage.getItem(key)) || []
      item.unshift(value)
      if (maxLen) {
        item.splice(maxLen)
      }
      localStorage.setItem(key, JSON.stringify(item))
      return item
    }

    // 通知
    function notify(title, opts, cb) {
      Notification.requestPermission(function (permission) {
        if (permission === 'granted') {
          let notification = new Notification(title, opts)
          if (typeof cb === 'function') {
            cb(notification)
          }
        }
      })
    }

    // 标记已处理
    $.fn.mark = function () {
      return this.css('text-decoration', 'line-through')
    }

    // 删除帖子
    function deleteQ(article) {
      // 上面是举报, 下面是删除
      $.post(`/action/communityManage/report?obj_id=${article.id}&obj_type=2&url=${encodeURIComponent(article.href)}&user_code=${userCode}&reason=1&memo=`, res => {
      //$.post(`/action/question/delete?id=${article.id}&hash=${article.hash}&user_code=${userCode}`, res => {
        if (res.length) {
          alert(res)
        }
      })
      lastDeleted = addLocalStorage('lastDeleted', article.title, 10)
    }

    function checkAD(doc) {
      let 疑似广告贴 = Array.from(doc.querySelectorAll('#HomeTopicPanel a[title]:not(.top), .list li:not(.top) a[target]')).map(a => ({ // 不检查置顶贴
          id: a.href.substr(a.href.indexOf('_') + 1),
          hash: getArticleHashCode(a.href),
          href: a.href,
          title: a.title || a.innerText,
          el: a,
          similaritySum: 0
        }))

        .filter(article => !reWhite.test(article.title) // 白名单过滤
          && !ignored.includes(article.id) // 已忽略的帖子
          // 已经举报/删除过的, 不处理并且从页面删掉
          && !(deleted.includes(article.id) && (doc == document ? $(article.el).parents('tr, li').first().mark() : true))
        )

        .map((article, idx, arr) => { // 计算和其他帖子的重复度
          for (let i = idx + 1, len = arr.length; i < len; ++i) {
            let similarity = calcSimilarity(article.title, arr[i].title)
            if (similarity >= similarityThreshold) { // 大于等于单条检测重复度阈值
              console.debug(similarity, article.title, arr[i].title)
              article.similaritySum += similarity
              arr[i].similaritySum += similarity
            }
          }
          lastDeleted.forEach(title => { // 计算和过去删除的十条帖子重复度
            let similarity = calcSimilarity(article.title, title)
            if (similarity >= similarityThreshold) { // 大于等于单条检测重复度阈值
              console.debug(similarity, article.title, 'last deleted: ' + title)
              article.similaritySum += similarity
            }
          })
          return article
        })

        .filter(article => article.similaritySum >= totalSimilarityThreshold) // 根据总重复度阈值过滤

      console.info(疑似广告贴)

      if (疑似广告贴.length >= suspiciousThreshold) {
        疑似广告贴.forEach(article => {
          notify('疑似广告贴', {
            body: article.title,
            tag: `report_${article.id}`
          }, notification => {
            notification.addEventListener('click', () => {
              deleteQ(article)
              deleted = addLocalStorage('deleted', article.id)
              if (doc == document) { // 如果在页面, 则删除对应的页面元素
                $(article.el).parents('tr').first().mark()
              }
              notification.close()
            })
            notification.addEventListener('close', () => {
              if (!deleted.includes(article.id)) {
                if (confirm(`是否忽略"${article.title}"?`)) {
                  ignored = addLocalStorage('ignored', article.id)
                } else {
                  deleteQ(article)
                  deleted = addLocalStorage('deleted', article.id)
                }
              }
            })
          })
        })
      }
    }

    checkAD(document)
    setTimeout(function intervalCheck() {
      $.get('/question?catalog=1&show=time', res => {
        checkAD(domParser.parseFromString(res, 'text/html'))
      })
      setTimeout(intervalCheck, checkInterval)
    }, checkInterval)
  }

  if (location.pathname == '/tweets') { // 在动弹页
    let hoveredlist=[];
    let checkInterval = 1e3 //检测间隔, 1秒
    function begin(){
      $("img[id^='tweet_img_']").each(function(){
          if(!hoveredlist.includes($(this).attr("id"))){
            hoveredlist.push($(this).attr("id"));
            $(this).hover(function(){
              var src=$(this).attr("src");
              localStorage.setItem($(this).attr("id"),src);
              $(this).attr("src",src.replace("_thumb",""));
              $(this).css("max-width","400px");
            },function(){
              $(this).attr("src",localStorage.getItem($(this).attr("id")));
              $(this).css("max-width","120px");
            });
          }
      });
    }
    setTimeout(function intervalCheck() {
      begin();
      setTimeout(intervalCheck, checkInterval)
    }, checkInterval)
  }

  if(location.pathname=='/'){
    $.get("http://www.oschina.net/tweets",
      function(t) {
          function e() {
              $.get("http://www.oschina.net/fetch_tweets",
              function(t) {
                  $("#tiles").html(t)
              },
              "html")
          }
          var o = $(t).find("#TForm").on("submit",
          function() {
              return $.post(o.attr("action"), o.serialize(),
              function(t) {
                  t.msg && alert(t.msg),
                  $("#TXT_Tweet_Text").val(""),
                  e()
              },
              "json"),
              !1
          });
          $("#QuestionWizard").empty().html("<style>#QuestionWizard{padding:0!important;height:auto!important;overflow:hidden}#TForm{position:relative;width:100%;padding-right:80px;box-sizing:border-box;background:#fff;height:auto!important;border:none!important;background:0;overflow:hidden!important;margin:0!important}#TForm input.B{position:absolute;top:0;right:0;width:80px;height:60px;line-height:60px;background:#5cc26f;color:#fff;border:0;font-size:11pt}#TForm textarea{border:0;width:100%;box-sizing:border-box;height:60px;padding:5px;font-size:10pt;resize:none}#TForm #TFormOpts ul{display:none}#tiles{border-top:1px solid #ccc;height:300px;overflow-y:scroll}#tiles::-webkit-scrollbar{width:3px}#tiles::-webkit-scrollbar-track-piece{background-color:rgba(0,0,0,0)}#tiles::-webkit-scrollbar-thumb{background:#eee}#tiles::-webkit-scrollbar-thumb:horizontal:hover{background:#ccc}#tiles a{margin:0!important;word-wrap:break-word}#tiles .tweet{font-size:9pt;text-align:left}</style>").append(o).append('<ul id="tiles"></ul>'),
          setInterval(e, 2e4),
          e()
      },
    "html");
  }
}()